home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Compilers⁄Interps / kevoSource / portWindows.c < prev    next >
Text File  |  1993-05-12  |  12KB  |  469 lines

  1. /* Kevo -- a prototype-based object-oriented language */
  2. /* (c) Antero Taivalsaari 1991-1993                   */
  3. /* Some parts (c) Antero Taivalsaari 1986-1988           */
  4. /* portWindows.c: Non-portable window operations       */
  5.  
  6. /*
  7.     This file contains structures and operations which are not 
  8.     portable from one machine platform to another.
  9. */
  10.  
  11. #include "global.h"
  12. #include "portGlobal.h"
  13.  
  14. /*---------------------------------------------------------------------------*/
  15. /* Generic printing operations */
  16.  
  17. /* 
  18.     These printing operations are pretty complicated, because the system must
  19.     automatically recognize whether the output device is a file (outfile != NIL),
  20.     or whether the window has a TextEdit or not. For files, we use normal C
  21.     fprintf function, but for other forms of I/O an appropriate toolbox routine
  22.     will be selected (either a TextEdit or QuickDraw routine).
  23. */
  24.  
  25. void ownPrintf(format, data)
  26. char* format;
  27. void* data;
  28. {
  29.   WindowPtr    thisWindow;
  30.   TEHandle    thisTE;
  31.   int        len;
  32.  
  33.     if (!outfile) {    /* Output to screen */
  34.  
  35.         /* If the task has no associated window, ignore printing */
  36.         thisWindow = (WindowPtr)(*up)->window;
  37.         if (!thisWindow) return;
  38.  
  39.         /* Format the data */
  40.         len = (unsigned char)sprintf(charbuffer, format, data);
  41.  
  42.         if (thisTE = getWindowTE(thisWindow)) { 
  43.             TEInsert(charbuffer, len, thisTE);
  44.         }
  45.         else {    /* window has no associated TE -> use QuickDraw */
  46.             GrafPtr savePort;
  47.  
  48.             GetPort(&savePort);
  49.             SetPort(thisWindow);
  50.             DrawString(CtoPstr(charbuffer));
  51.             SetPort(savePort);
  52.         }
  53.     }
  54.     else {    /* Output to file */
  55.          fprintf(outfile, format, data);
  56.           fflush(outfile);
  57.     }    
  58. }
  59.         
  60.  
  61. /* 
  62.     This operation is needed, because files and screen use different characters 
  63.     for separating the lines (files = LF, screen = CR). 
  64. */
  65.  
  66. void ownCr()
  67. {
  68.   WindowPtr    thisWindow;
  69.   TEHandle     thisTE;
  70.   
  71.     if (!outfile) {    /* Output to screen */
  72.     
  73.         /* If the task has no associated window, ignore printing */
  74.         thisWindow = (WindowPtr)(*up)->window;
  75.         if (!thisWindow) return;
  76.  
  77.         if (thisTE = getWindowTE(thisWindow)) TEKey(CR, thisTE); 
  78.         else {    /* window has no associated TE -> use QuickDraw */
  79.             GrafPtr savePort;
  80.             Point   pt;
  81.  
  82.             GetPort(&savePort);
  83.             SetPort(thisWindow);
  84.             GetPen(&pt);
  85.             /* Try to approximate a correct pen movement */
  86.             pt.h = 4;
  87.             pt.v += 12;
  88.             MoveTo(pt.h, pt.v);
  89.             SetPort(savePort);
  90.         }
  91.     } 
  92.     else {    /* Output to file */
  93.         fprintf(outfile, "\n");
  94.         fflush(outfile);
  95.     }  
  96. }
  97.  
  98.  
  99. /*---------------------------------------------------------------------------*/
  100. /* Window information field operations */
  101.  
  102. /* Create a window information structure */
  103. /* 
  104.     Each Kevo window must contain one of these structures stored
  105.     its 'RefCon' field.
  106. */
  107.  
  108. WINFO* createWinfo(kind, conf1)
  109. int     kind;    /* Window kind (see 'portGlobal.h') */
  110. void*     conf1;    /* Additional window information */
  111. {
  112.   WINFO* newWinfo = (WINFO*)mycalloc(1, sizeof(WINFO));
  113.   
  114.   newWinfo->wKind  = kind;
  115.   newWinfo->wConF1 = conf1;
  116.   newWinfo->wConF2 = 0;
  117.   newWinfo->wConF3 = 0;
  118.   
  119.   return (newWinfo);
  120. }
  121.  
  122.  
  123. /* Delete a window information structure */
  124. /*
  125.     Note that this routine does not delete the possible associated
  126.     TextEdit or List structure.
  127. */
  128. void deleteWinfo(thisWindow)
  129. WindowPtr thisWindow;
  130. {
  131.   WINFO* thisWinfo = (WINFO*)GetWRefCon(thisWindow);
  132.  
  133.     free(thisWinfo);
  134. }
  135.  
  136.  
  137. /* Return the window information field */
  138.  
  139. TEHandle getWindowTE(thisWindow)
  140. WindowPtr thisWindow;
  141. {
  142.   WINFO* thisWinfo = (WINFO*)GetWRefCon(thisWindow);
  143.  
  144.     if (thisWinfo && thisWinfo->wKind == TEWKind) 
  145.          return((TEHandle)thisWinfo->wConF1);
  146.     else return(NIL);
  147. }
  148.  
  149.  
  150. /* Return window kind info */
  151.  
  152. int getWindowKind(thisWindow)
  153. WindowPtr thisWindow;
  154. {
  155.   WINFO* thisWinfo = (WINFO*)GetWRefCon(thisWindow);
  156.   
  157.     if (thisWinfo) return(thisWinfo->wKind);
  158.     else return(UnknownWKind);
  159. }
  160.  
  161.  
  162. ListHandle getBrowserIcons(browserWindow)
  163. WindowPtr browserWindow;
  164. {
  165.   WINFO* thisWinfo = (WINFO*)GetWRefCon(browserWindow);
  166.   
  167.     if (thisWinfo && (thisWinfo->wKind == BrowserWKind || thisWinfo->wKind == CloneBrWKind))
  168.           return((ListHandle)thisWinfo->wConF1);
  169.       else return(NIL);
  170. }
  171.  
  172.  
  173. void setBrowserIcons(browserWindow, iconList)
  174. WindowPtr    browserWindow;
  175. ListHandle    iconList;
  176. {
  177.   WINFO* thisWinfo = (WINFO*)GetWRefCon(browserWindow);
  178.   
  179.     if (thisWinfo) thisWinfo->wConF1 = iconList;
  180. }
  181.         
  182.  
  183. char* getBrowserIdent(browserWindow)
  184. WindowPtr browserWindow;
  185. {
  186.   WINFO* thisWinfo = (WINFO*)GetWRefCon(browserWindow);
  187.  
  188.     if (thisWinfo && thisWinfo->wKind == BrowserWKind)
  189.           return((char*)thisWinfo->wConF2);
  190.       else return(NIL);
  191. }
  192.  
  193.  
  194. void setBrowserIdent(browserWindow, ident)
  195. WindowPtr    browserWindow;
  196. char*        ident;
  197. {
  198.   WINFO* thisWinfo = (WINFO*)GetWRefCon(browserWindow);
  199.   
  200.     if (thisWinfo) thisWinfo->wConF2 = ident;
  201. }
  202.         
  203.  
  204. OBJECT* getMethodContext(browserWindow)
  205. WindowPtr browserWindow;
  206. {
  207.   WINFO* thisWinfo = (WINFO*)GetWRefCon(browserWindow);
  208.   
  209.     if (thisWinfo && thisWinfo->wKind == TEWKind)
  210.           return((OBJECT*)thisWinfo->wConF2);
  211.       else return(NIL);
  212. }
  213.  
  214.  
  215. void setMethodContext(browserWindow, object)
  216. WindowPtr    browserWindow;
  217. OBJECT*     object;
  218. {
  219.   WINFO* thisWinfo = (WINFO*)GetWRefCon(browserWindow);
  220.   
  221.     if (thisWinfo) thisWinfo->wConF2 = object;
  222. }
  223.         
  224.  
  225. PAIR* getMethodPair(browserWindow)
  226. WindowPtr browserWindow;
  227. {
  228.   WINFO* thisWinfo = (WINFO*)GetWRefCon(browserWindow);
  229.   
  230.     if (thisWinfo && thisWinfo->wKind == TEWKind)
  231.           return((PAIR*)thisWinfo->wConF3);
  232.       else return(NIL);
  233. }
  234.  
  235.  
  236. void setMethodPair(browserWindow, pair)
  237. WindowPtr    browserWindow;
  238. PAIR*         pair;
  239. {
  240.   WINFO* thisWinfo = (WINFO*)GetWRefCon(browserWindow);
  241.   
  242.     if (thisWinfo) thisWinfo->wConF3 = pair;
  243. }
  244.         
  245.  
  246. /*---------------------------------------------------------------------------*/
  247. /* User interface tools */
  248.  
  249. /* Build a plain window (without any TE facilities) */
  250. WindowPtr buildWindow(title)
  251. char* title;
  252. {
  253.   WindowPtr origWindow = NIL;
  254.   WindowPtr    newWindow;
  255.   Rect        newRect;
  256.   WINFO*    newWinfo;
  257.   WStateData** wDataHdl;
  258.   static    count1 = 0;        /* Note: this is a static variable */
  259.   static    count2 = 0;        /* Note: this is a static variable */
  260.   
  261.     /* If we are not in the supervisor mode, and the task which is creating */
  262.     /* the new window has a window, copy size information from that window */
  263.     /* Otherwise, copy the info from the frontmost window on the screen */
  264.  
  265.     if (!supervisor) origWindow = (WindowPtr)(*up)->window;
  266.     if (!origWindow) origWindow = FrontWindow();
  267.  
  268.     /* Copy size information from the currently active window */
  269.     BlockMove(&origWindow->portRect, &newRect, sizeof(Rect));
  270.     ++count1;
  271.  
  272.     /* Place the window below and right of the current window */
  273.     OffsetRect(&newRect, 60 + count1*10 + count2*7, 80 + count1*10 + count2*3);
  274.     if (count1 > 20) {
  275.         count1 = 0;
  276.         count2++;
  277.         if (count2 > 15) count2 = 0;
  278.     }
  279.  
  280.     /* New window is created under the frontmost window */
  281.     if (!(newWindow = NewWindow(0L, /* Storage: from heap` */
  282.             &newRect,             /* Location and size rectangle */
  283.             title,                 /* The title of the window */
  284.             FALSE,                 /* Initially visible: false */
  285.             documentProc+8,     /* The kind of the window */
  286.             FrontWindow(),         /* Is behind the frontmost window */
  287.             TRUE,                 /* Has a close box: yes */
  288.             0L)))                 /* refCon field is initially NIL */
  289.         return(NIL);
  290.  
  291.     /* Set the standard size of the window for zooming */
  292.     wDataHdl = (WStateData**)((WindowPeek)newWindow)->dataHandle;
  293.     BlockMove(&standardRect, &(*wDataHdl)->stdState, sizeof(Rect));
  294.  
  295.     /* Create a window information structure for a plain window */
  296.     newWinfo = createWinfo(PlainWKind, NIL);
  297.     
  298.     /* Then set the RefCon field of the new window to point to the winfo struct */
  299.     SetWRefCon(newWindow, (long)newWinfo);
  300.  
  301.     return(newWindow);
  302. }
  303.  
  304.  
  305. /* Build a window with TE facilities */
  306. WindowPtr buildTEWindow(title)
  307. char*     title;
  308. {
  309.   WindowPtr    newWindow, savePort;
  310.   Rect        viewRect, destRect;
  311.   TEHandle    newText;
  312.   WINFO*    thisWinfo;
  313.   
  314.     if (!(newWindow = buildWindow(title))) return(NIL);
  315.  
  316.       GetPort(&savePort);
  317.     SetPort(newWindow);
  318.  
  319.     TextFont(monaco);
  320.     TextFace(0);
  321.     TextSize(9);
  322.  
  323.     BlockMove(&newWindow->portRect, &viewRect, sizeof(Rect));
  324.         viewRect.right  -= SCROLLBARWIDTH;
  325.         viewRect.bottom -= SCROLLBARWIDTH;
  326.     BlockMove(&newWindow->portRect, &destRect, sizeof(Rect));
  327.         destRect.right  -= (SCROLLBARWIDTH + 4);
  328.         destRect.bottom -= (SCROLLBARWIDTH + 4);
  329.         destRect.left   += 4;
  330.     
  331.     newText = TENew(&destRect, &viewRect);
  332.     if (!newText) return(NIL);    
  333.  
  334.     SetPort(savePort);
  335.  
  336.     /* Set automatic scrolling */
  337.     TEAutoView(TRUE, newText);
  338.  
  339.     /*
  340.         Change the associated window information struct to reflect on
  341.         the fact that the window is now a TextEdit window.
  342.     */
  343.     thisWinfo = (WINFO*)GetWRefCon(newWindow);
  344.     thisWinfo->wKind = TEWKind;
  345.     thisWinfo->wConF1 = newText;
  346.     
  347.     return(newWindow);
  348. }
  349.  
  350.  
  351. /* Given a window, find a foreground task which is associated to that window */
  352. /* Return NIL if the window has no associated foreground task */
  353. TASK** determineTask(thisWindow)
  354. WindowPtr thisWindow;
  355. {
  356.   TASK** thisTask = firstTask;
  357.  
  358.     /* Walk through all the tasks in the system */
  359.     /* and return the first one pointing to the requested window */
  360.     /* This is normally the task which originally created the window */
  361.     /* (unless the original task has been deleted) */
  362.     while(thisTask) {
  363.         if ((WindowPtr)(*thisTask)->window == thisWindow) return(thisTask);
  364.         thisTask = (*thisTask)->nextTask;
  365.     }
  366.     
  367.     return(NIL);
  368. }
  369.  
  370.  
  371. /* Given a window, delete it and all the associated tasks */
  372. /* provided that none of these tasks is running */
  373. /* Also delete the window information structure stored in the RefCon field */
  374. void deleteWindow(thisWindow)
  375. WindowPtr thisWindow;
  376. {
  377.   TASK** thisTask;
  378.   int     success = TRUE;
  379.   
  380.     while((thisTask = determineTask(thisWindow)) && (success = killTask(thisTask)));
  381.  
  382.     if (success) {
  383.         /* Tasks were deleted without any problems */
  384.         TEHandle thisTE = getWindowTE(thisWindow);
  385.         if (thisTE) TEDispose(thisTE);
  386.         deleteWinfo(thisWindow);
  387.         DisposeWindow(thisWindow);
  388.         theText = NIL;
  389.         /* theTask = NIL; */
  390.     }
  391.     else {
  392.         /* Otherwise the window cannot be closed */
  393.         theTask = thisTask;
  394.         fprintf(confile, "== Cannot delete the only active task in the system ==\n");
  395.     }
  396. }
  397.  
  398.  
  399. /* Given a window, resize the window by doing the appropriate changes
  400. /* in its possible TE structure */
  401. void resizeWindowTE(thisWindow)
  402. WindowPtr thisWindow;
  403. {
  404.   TEHandle    thisTE;
  405.   Rect        viewRect, destRect;
  406.     
  407.     if (thisTE = getWindowTE(thisWindow)) {
  408.         BlockMove(&thisWindow->portRect, &viewRect, sizeof(Rect));
  409.             viewRect.right  -= SCROLLBARWIDTH;
  410.             viewRect.bottom -= SCROLLBARWIDTH;
  411.         BlockMove(&thisWindow->portRect, &destRect, sizeof(Rect));
  412.             destRect.right  -= (SCROLLBARWIDTH + 4);
  413.             destRect.bottom -= (SCROLLBARWIDTH + 4);
  414.             destRect.left   += 4;
  415.  
  416.         BlockMove(&viewRect, &(*thisTE)->viewRect, sizeof(Rect));
  417.         BlockMove(&destRect, &(*thisTE)->destRect, sizeof(Rect));
  418.         
  419.         TECalText(thisTE);
  420.         TESelView(thisTE);
  421.     }
  422. }
  423.  
  424.  
  425. /* Count the number of visible windows (belonging to Kevo) */
  426.  
  427. int countVisibleWindows()
  428. {
  429.   WindowPeek thisWindow = (WindowPeek)FrontWindow();
  430.   int count = 0;
  431.   
  432.       while (thisWindow) {
  433.           if (thisWindow->visible) count++;
  434.           thisWindow = thisWindow->nextWindow;
  435.       }
  436.       return(count);
  437.  }
  438.  
  439.  
  440. /* 
  441.     Replace possible meta characters from window names with "safe" chars. 
  442.     Meta characters would cause the window menus entries to be blurred.
  443. */
  444. void replaceMenuMetas(string)
  445. char* string;    /* The parameter is actually a Pascal string */
  446. {
  447.     short len = (short)*string;
  448.     char* ptr = string+1;
  449.  
  450.     while (len--) {
  451.         switch (*ptr) {
  452.             case ';':
  453.             case '^':
  454.             case '!':
  455.             case '<':
  456.             case '/':
  457.             case '(':
  458.             /* The rest are not metas but are replaced anyway */
  459.             case ')':
  460.             case '>': 
  461.                 *ptr = '_';
  462.                 break;
  463.         }
  464.         ptr++;
  465.     }
  466. }
  467.  
  468.  
  469.